#ifndef _MB_DATAMODEL_H_
#define _MB_DATAMODEL_H_

#define DISINPUT_BUF_SIZE   16
#define COILS_BUF_SIZE      16
#define INPUTREG_BUF_SIZE   64
#define HOLDREG_BUF_SIZE    128

/**
 * 本模型依据 GB/T 1958.2-1 2008 第五页 建立
 * 内存数据模型，本模型是含有4个独立块的设备，表示了含有数字量，模拟量，输入量和输出量的数据组织,
 * 由于不同块的数据不相关，因此每个块是相互独立的，这样可通过不同的Modbus功能块访问每个块。
 * 
 * 寻址说明：
 * 1.内存基本单位：Byte
 * 2.地址按字节顺序编码
*/

#include "stdint.h"

#define MB_DATAMODEL_MAX_SLAVEID      128
#define MB_DATAMODEL_MAX_REGISTER_LEN 65535

#define MB_BIT_SET(x, n) (x | (1u << (n)))
#define MB_BIT_RESET(x, n) (x & (~(1u << (n))))

#define MB_PP_HTONS(X)  ((((uint16_t)(X) & 0xff00) >> 8) | (((uint16_t)(X) & 0x00ff) << 8))
#define MB_PP_HTONL(X)      ((uint32_t)(X) & 0xff000000) >> 24 | \
                            ((uint32_t)(X) & 0x00ff0000) >> 8  | \
                            ((uint32_t)(X) & 0x0000ff00) << 8  | \
                            ((uint32_t)(X) & 0x000000ff) << 24 |     

#define MB_PP_NTOHS(X)  ((((uint16_t)(X) & 0xff00) >> 8) | (((uint16_t)(X) & 0x00ff) << 8))
#define MB_PP_NTOHL(X)      ((uint32_t)(X) & 0xff000000) >> 24 | \
                            ((uint32_t)(X) & 0x00ff0000) >> 8  | \
                            ((uint32_t)(X) & 0x0000ff00) << 8  | \
                            ((uint32_t)(X) & 0x000000ff) << 24 | 
                            

typedef struct __MB_DATAMODEL_HandleTypeDef
{
  //离散输入  DI
  uint8_t                  *pDiscretesInputBuffPtr;    //离散输入存储器的指针
  uint16_t                  DiscretesInputBufSize;     //离散输入存储器的大小
  //线圈      DO
  uint8_t                  *pCoilsBuffPtr;             //线圈存储器的指针
  uint16_t                  CoilsBufSize;              //线圈存储器的大小
  //输入寄存器 AI
  uint8_t                  *pInputRegistersBuffPtr;    //输入存储器的指针
  uint16_t                  InputRegistersBufSize;     //输入存储器的大小
  //保存寄存器 V
  uint8_t                  *pHoldingRegistersBuffPtr;  //保持存储器的指针
  uint16_t                  HoldingRegistersBufSize;   //保持存储器的大小
}MB_DATAMODEL_HandleTypeDef;

typedef struct __MB_DATA_HandleTypeDef
{
  //离散输入  DI
  uint8_t                  DiscretesInputBuf[DISINPUT_BUF_SIZE];    //离散输入存储器的指针
  //线圈      DO
  uint8_t                  CoilsBuf[COILS_BUF_SIZE];             //线圈存储器的指针
  //输入寄存器 AI
  uint8_t                  InputRegistersBuf[INPUTREG_BUF_SIZE];    //输入存储器的指针
  //保存寄存器 V
  uint8_t                  HoldingRegistersBuf[HOLDREG_BUF_SIZE];  //保持存储器的指针
}MB_DATA_HandleTypeDef;

#endif
